
import math
import csv
import matplotlib.pyplot as plt
import numpy as np
import decompose_hc
import load_coeffs

# 读取 CSV 文件
def read_csv_file(file_path):
    with open(file_path, 'r') as file:
        reader = csv.reader(file)
        data = [row for row in reader]
    return data


def predict_xy_edge_crack_2d(E,D,a,x,y,num_harmonics):

    coefficients_normal,coefficients_tangent=load_coeffs.get_coeffs()    
    n=len(x)
    thea=np.linspace(0,2.0*np.pi,n+1)
    thea=thea[:-1]
    u=x
    v=y
   
    coeffs_u=decompose_hc.decompose(thea,u,num_harmonics)
    coeffs_v=decompose_hc.decompose(thea,v,num_harmonics)
    
    print("--------------------predict------------------------")
   
    #in csv file ,the order is ：normal_coeff 为 1 cosx cos2x.....sinx sin2x...
    #for calculating, change order into：1 cosx sinx cox2x sin2x ...
    def re_order(coeffs_u):
        N=len(coeffs_u)
        new_coeffs_u=[coeffs_u[0]]
        for i in range(1,N//2+1):
            new_coeffs_u.append(coeffs_u[i])
            new_coeffs_u.append(coeffs_u[i+N//2])
        return new_coeffs_u
    coeffs_u=re_order(coeffs_u)
    coeffs_v=re_order(coeffs_v)

    normal_coeff=coeffs_u
    tangent_coeff=coeffs_v
    
    k=load_coeffs.eval_K(E,a,D,num_harmonics*2+1,coefficients_normal,coefficients_tangent,normal_coeff,tangent_coeff)
    return k

def run_edge_crack_2d(disp_file,a_2c,E):
    order=8
    grid_cells=read_csv_file(disp_file)

    c1_k1vs_r=[]
    c1_k2vs_r=[]
    c2_k1vs_r=[]
    c2_k2vs_r=[]

    r_list=[ float(grid_cells[2][i]) for i in range(len(grid_cells[2])) if grid_cells[2][i]!='']
    grid_cells=grid_cells[3:]

    grid_cells_fliter=[]
    for item in grid_cells:
        line=[item[i] for i in range(len(item)) if item[i]!="" and item[i]!=" "]
        grid_cells_fliter.append(line)
    
    
    grid_cells=grid_cells_fliter
      
    r_in_range=[]
    coeffs_list=[]
    for i in range(0,len(r_list)*2,2):

    #for i in range(0,len(grid_cells[-1]),2):
        u=[]
        v=[]
        
        for j in range(len(grid_cells)):
            u.append(float(grid_cells[j][i]))
            v.append(float(grid_cells[j][i+1]))
        
        Rc=r_list[i//2]
        a_d=a_2c/(Rc*2)
        #   D,a,x,y,num_harmonics                                                               弹性模量换算
        k1=predict_xy_edge_crack_2d(E,Rc*2,a_2c,u,v,order)
        print("D=",Rc*2,"2a=",a_2c,"predict k1=",' '.join([str(item*E/192000) for item in k1]))
        c1_k1vs_r.append(k1[0]*E/192000)
        c1_k2vs_r.append(k1[1]*E/192000)
        c2_k1vs_r.append(k1[2]*E/192000)
        c2_k2vs_r.append(k1[3]*E/192000)
        r_in_range.append(Rc*2/a_2c)


    if len(r_in_range)>0:

        stype = "plot"
        if stype=="bar":
            # 图形设置
            plt.figure(figsize=(15, 7))

            # 计算每个柱子的宽度
            bar_width = 0.2  # 柱子的宽度
            index = np.arange(len(r_in_range))  # 柱子的位置

            # 绘制柱状图
            plt.bar(index, c1_k1vs_r, width=bar_width, label="C1-K1 vs r", alpha=0.7)
            plt.bar(index + bar_width, c1_k2vs_r, width=bar_width, label="C1-K2 vs r", alpha=0.7)

            # 设置标题和标签
            plt.title("Dispersion Curves")
            plt.xlabel("r")
            plt.ylabel("K")

            # 设置 x 轴刻度和标签
            plt.xticks(index + bar_width, r_in_range)

            # 设置坐标轴范围
            plt.xlim(-bar_width, 1.2*(len(r_in_range) + bar_width))  # 设置 x 轴范围
            plt.ylim(0, 1.2*max(max(c1_k1vs_r), max(c1_k2vs_r)))  # 设置 y 轴范围

            # 添加图例和网格
            plt.legend()
            plt.grid(True)

            # 显示图形
            plt.show()
        if stype=="plot":
            plt.figure(figsize=(15, 7))
            # 绘制曲线
            plt.plot(r_in_range, c1_k1vs_r, marker="o", linestyle="-", label="C1_K1 vs r", alpha=0.7)      
            plt.plot(r_in_range, c1_k2vs_r, marker="p", linestyle="--", label="C1_K2 vs r", alpha=0.7)
            plt.plot(r_in_range, c2_k1vs_r, marker="*", linestyle="-", label="C2_K1 vs r", alpha=0.7)      
            plt.plot(r_in_range, c2_k2vs_r, marker="+", linestyle="--", label="C2_K2 vs r", alpha=0.7)
            
            for i in range(len(r_in_range)):
                    plt.annotate(f"{c1_k1vs_r[i]:.2f}", 
                            (r_in_range[i], c1_k1vs_r[i]), 
                            textcoords="offset points", 
                            xytext=(10, 10), 
                            ha='center')


                    plt.annotate(f" {c1_k2vs_r[i]:.2f}", 
                        (r_in_range[i], c1_k2vs_r[i]), 
                        textcoords="offset points", 
                        xytext=(-10, 10), 
                        ha='center')
    # 设置标题和标签
            plt.title("Dispersion Curves")
            plt.xlabel("r")
            plt.ylabel("K")

    # 设置坐标轴范围
            # 设置坐标轴范围，确保从 (0, 0) 开始
            plt.xlim(0, 1.2*max(r_in_range))  # 设置x轴范围从0开始，到数据的最大值
            plt.ylim(0, 1.2*max(max(c1_k1vs_r), max(c1_k2vs_r)))  # 设置y轴范围从0开始
            plt.ylim(min(min(c1_k1vs_r),min(c1_k2vs_r)) - 0.1,max(max(c1_k1vs_r),  max(c1_k2vs_r)) + 0.1)



            plt.legend()
            plt.grid(True)
            plt.show()  

            #r_in_range=裂纹尺寸2a/D 
    return [r_in_range,c1_k1vs_r,c1_k2vs_r]